<?php

namespace App\Http\Controllers;

use App\Events\NoticeChange;
use App\Events\Sale;
use App\Events\SellChange;
use App\Models\Balance;
use App\Models\Bankcard;
use App\Models\Sell;
use Illuminate\Http\Request;

class SellController extends Controller
{
  public function index(Request $request)
  {
    $page = Sell::with('member', 'seller:id,username')
      ->when($request->has('member_username'), function ($q) use ($request) {
        $q->whereHas('member', function ($q) use ($request) {
          $q->where('username', $request->member_username);
        });
      })
      ->when($request->has('seller_username'), function ($q) use ($request) {
        $q->whereHas('seller', function ($q) use ($request) {
          $q->where('username', $request->seller_username);
        });
      })
      ->when($request->has('state'), function ($q) use ($request) {
        $q->where('state', $request->state);
      }, function ($q) {
        // $q->today();
      })
      ->orderByRaw("FIELD(state, 'checking', 'pending') desc")
      ->orderBy('id', 'desc')
      ->page();

    return success($page);
  }

  public function indexForMember(Request $request)
  {
    $page = Sell::select('id', 'coins', 'state', 'created_at')
      ->when($request->has('state'), function ($q) use ($request) {
        $q->where('state', $request->state)
          ->where('member_id', auth()->id());
      }, function ($q) {
        $q->where('state', 'pending');
      })
      ->with('seller:id,username,avatar')
      ->latest()
      ->page(20);

    return success($page);
  }

  public function indexForAgent(Request $request)
  {
    $page = Sell::latest()
      ->when($request->has('state'), function ($q) use ($request) {
        $q->where('state', $request->state);
      })
      ->with('member:id,username,avatar')
      ->where('state', 'pass')
      ->page();

    return success($page);
  }

  public function indexForSeller(Request $request)
  {
    $page = Sell::when($request->has('id'), function ($q) {
      $q->where('id', request('id'));
    })
      ->select('id', 'member_id', 'coins', 'state', 'created_at', 'done_at', 'realname', 'bank', 'bankcard')
      ->with('member:id,username,avatar')
      ->state('done')
      ->where('seller_id', sellerId())
      ->latest()
      ->page();

    return success($page);
  }

  public function passIndexForSeller(Request $request)
  {
    $page = Sell::select('id', 'member_id', 'coins', 'state', 'created_at', 'done_at', 'realname', 'bank', 'bankcard')
      ->when($request->has('id'), function ($q) {
        $q->where('id', request('id'));
      })
      ->with('member:id,username,avatar')
      ->whereNull('seller_id')
      ->state('pass')
      ->latest()
      ->page();

    return success($page);
  }

  public function store(Request $request)
  {
    if (floatval($request->coins) < 0) {
      fail('卖币金额不正确');
    }
    if ($request->coins < sys('sell_min_coins')) {
      fail('最小卖币') . sys('sell_min_coins');
    }

    if ($request->coins > auth()->user()->coins) {
      fail('卖币金额不正确');
    }

    $sell = \DB::transaction(function () use ($request) {
      $bankcard = Bankcard::lockForUpdate()->findOrFail($request->bankcard_id);
      $member = auth()->user();
      $member->lockForUpdate();

      $sell = Sell::create([
        "id" => app('snowflake')->id(),
        'member_id' => auth()->id(),
        'coins' => $request->coins,
        'agent_id' => $member->pid,
        'bank' => $bankcard->bank,
        'bankcard' => $bankcard->number,
        'realname' => $member->realname
      ]);

      $member->coinsChange(-$request->coins, '用户卖币', $sell->id);

      return $sell;
    });

    broadcast(new SellChange($sell->id, 'store'))->toOthers();
    event(new NoticeChange());

    return success('ok');
  }

  public function statis()
  {
    $counts = Sell::where('member_id', auth()->id())
      ->select(\DB::raw('count(*) as count, state'))
      ->groupBy('state')
      ->get()
      ->flatMap(function ($item) {
        return [
          $item->state => $item->count
        ];
      });

    return success($counts);
  }

  public function review(Sell $sell, Request $request)
  {
    $request->validate([
      'state' => 'required|in:pass,reject'
    ]);
    //审核用户卖出
    if ($sell->state === 'pending') {
      $sell->state = $request->state;
      $sell->save();

      if ($request->state === 'pass') {
        event(new SellChange($sell->id, 'pass'));
      }

      if ($request->state === 'reject') {
        $sell->member->coinsChange($sell->coins, '用户卖币被拒', $sell->id);
      }
    }
    //审核商家买入
    if ($sell->state === 'checking') {
      // 审核通过商户会加FCB
      if ($request->state === 'pass') {
        \DB::transaction(function () use ($sell) {
          $sell->state = 'done';
          $sell->save();

          $sell->seller->coinsChange($sell->coins, '商户买币', $sell->id);
        });
      }

      if ($request->state === 'reject') {
        // 拒绝，这笔订单退回到商户买币列表
        $sell->state = 'pass';
        $sell->seller_id = null;
        $sell->save();
      }
    }
    event(new SellChange($sell->id, $sell->state, $sell->member_id, $sell->seller_id));
    return success('ok');
  }

  public function sold($id)
  {
    \DB::transaction(function () use ($id) {
      $sell = Sell::lockForUpdate()->findOrFail($id);
      if ($sell->state !== 'locking') {
        fail('状态错误');
      }

      $seller = seller();
      $sell->update([
        'seller_id' => $seller->id,
        'state' => 'checking',
        'done_at' => now()
      ]);
    });
    broadcast(new SellChange($id, 'sold'))->toOthers();
    event(new NoticeChange());
    return success('ok');
  }

  public function unlock($id)
  {
    \DB::transaction(function () use ($id) {
      $sell = Sell::lockForUpdate()->findOrFail($id);
      if ($sell->state !== 'locking') {
        fail('状态错误');
      }

      $sell->update([
        'seller_id' => null,
        'state' => 'pass',
      ]);
    });

    broadcast(new SellChange($id, 'unlock'))->toOthers();
    return success('ok');
  }

  public function unlockByAdmin($id)
  {
    return $this->unlock($id);
  }

  public function lock($id)
  {
    \DB::transaction(function () use ($id) {
      $sell = Sell::lockForUpdate()->findOrFail($id);
      if ($sell->state !== 'pass') {
        fail('订单状态错误');
      }

      $seller = seller();
      $sell->update([
        'seller_id' => $seller->id,
        'state' => 'locking',
      ]);
    });

    event(new SellChange($id, 'lock'));
    return success('ok');
  }

  /**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\Models\Sell  $sell
   * @return \Illuminate\Http\Response
   */
  public function update(Request $request, Sell $sell)
  {
    //
  }

  /**
   * Remove the specified resource from storage.
   *
   * @param  \App\Models\Sell  $sell
   * @return \Illuminate\Http\Response
   */
  public function destroy(Sell $sell)
  {
    //
  }
}
